package com.fulu.game.bi.service.impl.auth.config;

import com.fulu.game.bi.AssertHelper;
import com.fulu.game.bi.entity.enums.UserStatus;
import com.fulu.game.bi.entity.po.auth.BiUser;
import com.fulu.game.bi.redis.service.auth.BiUserService;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.Optional;

/**
 * 通过用户名和密码获取用户信息
 */
@Slf4j
public class BiUsernamePasswordRealm extends AuthorizingRealm {

    @Autowired
    private BiUserService biUserService;

    /**
     * 验证当前登录的用户，获取认证信息
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {

        String userName = (String) token.getPrincipal();

        //这里可以根据实际情况做缓存;
        // 如果不做，Shiro有时间间隔机制，2分钟内不会重复执行该方法
        BiUser user = biUserService.findByUserName(userName);

        log.info("Realm 验证开始，用户信息为 {}", user);

        Optional.ofNullable(user).orElseThrow(UnknownAccountException::new);
        AssertHelper.assertFalse(UserStatus.DISABLE.getType().equals(user.getStatus()), LockedAccountException::new);

        String password = user.getPassword();
        String salt = user.getSalt();

        return new SimpleAuthenticationInfo(
                user,
                password,
                ByteSource.Util.bytes(salt),
                getName()
        );
    }
    
    /**
     * 为当前登录成功的用户授予权限和分配角色。
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        // 获取用户名
        String username = (String) principalCollection.getPrimaryPrincipal();
        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
        // 给该用户设置角色，角色信息存在 t_role 表中取
        authorizationInfo.setRoles(biUserService.getRoles(username));
        // 给该用户设置权限，权限信息存在 t_permission 表中取
        authorizationInfo.setStringPermissions(biUserService.getPermissions(username));
        return authorizationInfo;
    }

}
